import type { Component, StyleHTMLAttributes } from "vue";

import type { VxeTablePropTypes, VxeColumnProps, VxeColumnPropTypes, VxeColumnSlotTypes } from "vxe-table";

import type { PaginationProps } from "element-plus";

import MerakXTable from "./index.vue";

type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

// 组件实例，可通过自定义 ref 调用组件暴露的方法
// reloadData 刷新列表
// reloadTable 重置列表(重置除外部筛选条件的所有内部搜索条件)
export type MerakXTableInstance = InstanceType<typeof MerakXTable>;

// 行数据类型定义
export type MerakXTableData = Record<string, any>;

// 表头筛选的值的类型定义
export type MerakXTableFilter = string | number;

// 表格分页设置的类型定义
export type MerakXTablePagination = Partial<Mutable<PaginationProps>>;

// 表格工具栏默认工具类型定义
export type MerakXTableToolbarType = "refresh" | "setting" | "export";

// 表格特殊类型列的默认类型定义
export type MerakXTableColumnType = "index" | "selection" | "multiple" | "expand" | "handle";

// 表格编辑参数
/**
 * 表格编辑参数
 * @param rowKey 行数据唯一 key(rowKey)
 * @param field 单元格所属字段
 * @param value 单元格值, 如果字段是枚举值且行数据中包含 field_val 字段则取 field_val 的值
 * @param text 单元格枚举值展示值
 * @param row 行数据
 */
export interface MerakXTableEditorParams {
  rowKey: string | number;
  field: string;
  value: any;
  text?: string;
  row?: Record<string, any>;
}

/**
 * 列类型定义
 * @param params 自定义的数据参数对象
 * @param slots 列的插槽定义对象
 * @param children 列集合的子集
 * @param other https://vxetable.cn/#/column/api
 */
export interface MerakXTableColumn<T = MerakXTableData> extends VxeColumnProps<T> {
  params?: {
    disabled?: boolean;
    editor?: boolean;
    summary?: number;
    summarySpan?: number;
    searchLoading?: boolean;
    searchType?: "input" | "select" | "date" | "daterange";
    searchValue?: any;
    searchDefaultValue?: any;
    searchOptions?: Array<{ value: string; label: string }>;
    otherWidth?: number;
    [x: string]: any;
  };
  slots?: VxeColumnPropTypes.Slots<T>;
  children?: MerakXTableColumn<T>[];
}

/**
 * 工具栏子项的类型定义
 * @param type 工具的 key
 * @param title 工具的展示文字
 * @param icon 工具前缀的 icon 图标
 */
export interface MerakXTableToolbar {
  type: MerakXTableToolbarType | string;
  title?: string;
  icon?: Component;
}

// 表格的数据请求值类型定义
export namespace MerakXTableQuery {
  /**
   * 列头数据请求返回值
   * @param pageSize 存在分页时需要返回的当前每页条数
   * @param columns 表头数据
   */
  export interface Columns<T = MerakXTableData> {
    pageSize?: number;
    table_id?: any;
    version?: any;
    columns: MerakXTableColumn<T>[];
  }

  /**
   * 用于请求列表数据时传入的参数类型定义
   * @param page 分页参数 - currentPage 当前页 - pageSize 当前每页条数
   * @param sorts 排序参数 - field 排序字段 - order 排序结果
   * @param filters 筛选参数 - field 筛选字段 - value 筛选结果
   * @param from 外部筛选数据对象
   */
  export interface Params<T = Record<string, any>> {
    page?: {
      currentPage: number;
      pageSize: number;
    };
    sort?: {
      field: string;
      order: VxeTablePropTypes.SortOrder;
    };
    sorts?: Array<{
      field: string;
      order: VxeTablePropTypes.SortOrder;
    }>;
    filters?: Array<{
      field: string;
      value: MerakXTableFilter | MerakXTableFilter[];
    }>;
    from?: T;
  }

  /**
   * 请求表格数据返回值
   * @param total 分页存在时需要返回数据统计
   * @param currentPage 分页存在时需要返回当前页
   * @param data 表格数据
   */
  export interface Records<T = MerakXTableData> {
    total?: number;
    currentPage?: number;
    list: T[];
  }
}

/**
 * 表格下拉菜单类型定义，用于批量操作和操作列
 * @param type 自定义 key
 * @param text 展示文字
 * @param color 文字颜色
 * @param divided 是否展示分割线
 * @param icon 前缀 icon 图标
 * @param disabled 禁用选项
 * @param onClick 自定义的触发方法，优先级高于 batchClick 和 handlerClick
 */
export interface MerakXTableDropdown {
  type: string;
  text?: ((row?: MerakXTableData) => string) | string;
  color?: StyleHTMLAttributes["color"];
  divided?: boolean;
  icon?: Component;
  disabled?: (row?: MerakXTableData) => boolean;
  visible?: (row?: MerakXTableData) => boolean | void;
  onClick?: (params?: any) => void;
}

/**
 * 表格属性参数类型定义
 * @param columnsByStore 用于列设置存储的原始表头数据的克隆值
 * @param loading 受控 loading 状态
 * @param maxFixed 列固定的最大数量(不包含特殊列)
 * @param maxHeight 表格最大高度 默认 100%
 * @param align 表格的对齐方式
 * @param headerAlign 表头的对齐方式
 * @param showHeader 是否显示表格顶部 默认 true
 * @param enabledTree 启用树层级结构 默认 false
 * @param enabledScroll 启用虚拟滚动 默认 true
 * @param enabledEditor 启用编辑 默认 false  PS: true: 所有字段全部开启 false: 允许column自己配置是否开启
 * @param enabledEditorByAuth 启用编辑通过权限验证 默认 true
 * @param enabledExport 启用导出 默认 true
 * @param treeTransform 虚拟滚动的情况下父子层级的结构数据转换为树层级结构(虚拟滚动下不支持树层级结构数据) 默认 false
 * @param treeExpandAll 树结构下展开所有子节点 默认 true
 * @param rowHeight 行高，虚拟滚动下仅支持等行高
 * @param rowKey 行数据的 key 字段值 默认 id
 * @param parentKey 父子层级树结构数据 子节点行数据的 key 字段值 默认 parentId
 * @param params 外部筛选参数对象，数据请求时会入参在 queryData 参数中 from 字段
 * @param awaitParams 是否等待外部筛选参数获取数据后开始查询表格数据 默认 false
 * @param data 表格数据
 * @param columns 表头数据
 * @param columnType 特殊列集合(序号列，选择列，展开列，操作列)
 * @param columnMinWidth 最小列宽
 * @param toolbar 工具栏数据集合
 * @param batches 批量操作下拉菜单选项数据集合
 * @param batchesAsyncLoading 批量操作异步loading状态
 * @param handles 操作列下拉菜单选项数据集合
 * @param handlesAsyncLoading 操作列异步loading状态
 * @param pagination 分页设置属性参数对象，设置为 false 禁用分页
 * @param batchClick 批量操作下拉菜单默认触发事件
 * @param handlerClick 操作列下拉菜单默认触发事件
 * @param queryColumns 代理请求表头数据的方法
 * @param queryOptions 代理请求表头筛选下拉选项数据的方法
 * @param queryData 代理请求表格数据的方法
 */
export interface MerakXTableProps<T = MerakXTableData, K = Record<string, any>> {
  columnsByStore: MerakXTableColumn<T>[];
  loading?: boolean;
  maxFixed?: number;
  maxHeight?: number | string;
  border?: boolean;
  align?: "center" | "left" | "right";
  headerAlign?: "center" | "left" | "right";
  showHeader?: boolean;
  enabledTree?: boolean;
  enabledScroll?: boolean;
  enabledEditor?: boolean;
  enabledEditorByAuth?: boolean;
  enabledExport?: boolean;
  treeTransform?: boolean;
  treeExpandAll?: boolean;
  rowHeight?: number;
  rowKey?: string;
  parentKey?: string;
  pictureExport?: boolean;
  params?: K;
  config?: { table_id?: string | number; version?: string | number };
  awaitParams?: boolean;
  data?: T[];
  columns?: MerakXTableColumn<T>[];
  columnType?: Array<
    | MerakXTableColumnType
    | {
        type: MerakXTableColumnType;
        width?: number;
        showHandleDropDown?: boolean;
        slot: string | ((params: VxeColumnSlotTypes.DefaultSlotParams) => any);
      }
  >;
  columnMinWidth?: number;
  toolbar?: Array<MerakXTableToolbarType | MerakXTableToolbar>;
  batches?: MerakXTableDropdown[];
  batchesAsyncLoading?: boolean;
  handles?: MerakXTableDropdown[];
  handlesAsyncLoading?: boolean;
  pagination?: false | MerakXTablePagination;
  batchClick?: (params: { type: string; mode: "current" | "all"; selectedKeys: string[] }) => Promise<{
    refresh?: boolean;
    reset?: boolean;
  } | void>;
  handlerClick?: (params: { type: string; params: VxeColumnSlotTypes.DefaultSlotParams<T> }) => Promise<boolean | void>;
  queryColumns?: () => Promise<MerakXTableQuery.Columns | void>;
  queryOptions?: (field: string) => Promise<Array<{
    value: string;
    label: string;
  }> | void>;
  queryData?: (params: MerakXTableQuery.Params) => Promise<MerakXTableQuery.Records | void>;
}

export default MerakXTable;
